Get_input proc far    
    ; 函数：获取用户输入  
    ; 参数：ds:si 录入数据的位置  al : 1 只接收数字 2 只接收字母 3 同时接收数字和字母 ah: 接收字符的长度
    ; 返回值：将录入的数据写在ds:si位置上  但是不改变si(保证不同长度输入结果si相同) al:输入字符串的长度

    ; 正常输入，将录入的数据写在ds:si位置上，只改变ax寄存器
    ; 输入超出范围，不写入数据，ax寄存器值为BADh
    ; 输入不符合要求，不写入数据，ax寄存器值为BADh


    push bp
    mov bp, sp
    push si
    push bx
    push cx
    push dx
 
    xor bx,bx   
    push bx  ;push 0
    xor cx,cx
    mov dx,si

    mov bl,al
    mov cl,ah
    add cl,1

    xor ax,ax

Get_input_cycle:
    
    mov ah, 1            ;21h-1号功能输入一个字符存入al
    int 21h 
    xor ah,ah
    cmp al, 0dh
    jz Get_input_write_Transfer    ; 接收到回车结束循环


    cmp al, 08h           ; 接收到退格键删除一个栈元素

    jnz Get_input_cycle_continue





    pop ax                ; 出栈一个元素
    dec dx
    dec ch

    
    cmp ax,0h    
    jnz Get_input_cursor_back  ;若该元素为00，放回栈,重新进入循环,光标位置不变，若不为00，回退一格光标,

    push ax
    inc dx
    inc ch
    ; 控制光标位置不变(光标前一格为空格)
    mov ah, 0eh
	mov al, 0eh
	int 10h
	mov al, ' '
	int 10h
	mov al, 08h
	int 10h	
	mov al, 08h
	int 10h	
	mov al, ' '
	int 10h

    jmp Get_input_cycle 

Get_input_cursor_back:
    ;回退光标
    mov ah, 0eh       

	mov al, 0eh     ;防止光标移动到上一行
	int 10h
	mov al, ' '   ;写入空格
	int 10h
	mov al, 08h   ;回退光标
	int 10h	
    jmp Get_input_cycle 



Get_input_cycle_continue:
    push ax               ;输入的字符暂存在栈中
    inc dx
    inc ch

    jmp  Get_input_cycle


Get_input_write_Transfer:
    jmp Get_input_write


Get_input_unexpected_Transfer:  ; 中转
    jmp Get_input_unexpected

check_include_numbers:  ;检查输入是否为数字

    cmp al,30h
    jb Get_input_unexpected_Transfer
    cmp al,39h
    jna Get_input_write_continue
    jmp Get_input_unexpected_Transfer

check_include_letters: ;检查输入是否为字母
    cmp al,20h
    jz Get_input_write_continue
    cmp al,41h
    jb Get_input_unexpected_Transfer
    cmp al,5ah
    jna Get_input_write_continue
    cmp al,61h
    jb Get_input_unexpected_Transfer
    cmp al,7ah
    jna Get_input_write_continue
    jmp Get_input_unexpected_Transfer


check_include_numbers_and_letters:  ;检查输入是否为数字或字母
    cmp al,20h
    jz Get_input_write_continue
    cmp al,30h
    jb Get_input_unexpected_Transfer
    cmp al,39h
    jna Get_input_write_continue
    cmp al,41h
    jb Get_input_unexpected_Transfer
    cmp al,5ah
    jna Get_input_write_continue
    cmp al,61h
    jb Get_input_unexpected_Transfer
    cmp al,7ah
    jna Get_input_write_continue
    jmp Get_input_unexpected_Transfer


Get_input_write:  ; 接收完毕，开始写入数据

    sub dx,1h
    mov si,dx

    cmp ch,cl
    jae  Get_input_out_of_range  ;超过接收字符的长度限制，报错



Get_input_write_cycle:   ; 提取并检查数据
    pop ax
    cmp ax,00h
    jz Get_input_done

    cmp bx,1
    jz check_include_numbers
    cmp bx,2
    jz check_include_letters
    cmp bx,3
    jz check_include_numbers_and_letters

    dispmsg parameter_error

Get_input_write_continue:   ; 写入数据
    mov ds:[si],al
    dec si
    jmp Get_input_write_cycle


Get_input_done:
    xor ah,ah
    mov al,ch   ; 传入输入字符的长度
Get_input_done2:   ;结束  恢复寄存器
    push ax
    dispmsg next_row
    pop ax
    pop dx
    pop cx 
    pop bx
    pop si
    pop bp
    retf




Get_input_unexpected:   ; 输入发生错误
    dispmsg next_row
    dispmsg Character_error
    jmp Get_input_clear_stack

Get_input_out_of_range:  ;输入超出长度限制
    dispmsg next_row
    dispmsg Length_error 
    jmp Get_input_clear_stack

Get_input_clear_stack:  ;清除栈
    pop ax    
    cmp ax,00h
    jnz Get_input_clear_stack
    cmp dx,00h
    jz Get_input_clear_write_finish
Get_input_clear_write:  ;清除已写入数据
    mov bx,0
    mov ds:[si],bx
    dec dx
    cmp dx,0
    jnz Get_input_clear_write
Get_input_clear_write_finish:
    mov ax,0BADh
    jmp Get_input_done2





Get_input endp

    ; mov ax,data
    ; mov ds,ax
    ; lea si,data_start
    ; mov ax,0E02h    ; 接收最大14字节的字母字符串
    ; call far ptr Get_input